﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace MMDemo
{
    /*
       *	枚举当前可执行类型
       */
    public enum LinkOperateType
    {
        InitNew,
        AddElement,
        Delete,
        Search,
    }
   
    class AnimationLink : InterfaceDataStructs
    {
        /// <summary>
        /// 类成员
        /// </summary>
        private Form Animation_Form = null;//演示窗体，用于构造函数的初始化
        private int Animation_width = 0;//演示窗体的宽度
        private int Animation_height = 0;//演示窗体的高度
        public Bitmap BufferBmp = null;//双缓冲画布
        private Graphics BufferGrap = null;//画笔
        private DrawHandler RefreshHandler = null;

        private char[] Link_Data;//链表元素

        private string adddata;//新增元素

        private int datalocate;//定位元素位置


        private const int MAX_SIZE = 26; //链表的最大数据容量



        public AnimationLink(Form An_Form, DrawHandler refreshHandler, int An_Width, int An_Height)
        {
            this.Animation_Form = An_Form;
            this.RefreshHandler = refreshHandler;
            this.Animation_width = An_Width;
            this.Animation_height = An_Height;
            Link_Data = new char[MAX_SIZE];
            //设置画布和画笔
            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);
        }

        public void SetAnimationFormSize(int Width, int Height)
        {
            this.Animation_width = Width;
            this.Animation_height = Height;
        }

        //定义用户选择执行类型，默认为新建
        public LinkOperateType operateType = LinkOperateType.InitNew;

        private const int SPEED = 100;
        private int _Speed = SPEED;//演示动画速度
        public void SetSpeed(float scale)
        {
            _Speed = (int)(SPEED * scale);
        }

        private bool stop_flag = false;//结束标志位

        //重新设置数据
        public bool ResetData(String data)
        {
            operateType = LinkOperateType.InitNew;
            // 去掉空字符
            data.Trim();
            SetExcuteLine(0);
            if (null == data)
            {
                SetExcuteLine(2);
                return false;
            }
            //把字母变成大小
            data = data.ToUpper();
            all_size = data.Length;
            cur_size = 0;
            for (int i = 0; i < data.Length; ++i)
            {
                Link_Data[i] = data[i];
            }
            return true;
        }

        /// <summary>
        /// 初始化链表数据的重载，用于初始化链表插入
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool ResetData(GlobalLink.LinkAddData data)
        {
            operateType = LinkOperateType.AddElement;
            string linkdata;
            // 去掉空字符
            linkdata = data.linkdata.Trim();
            SetExcuteLine(0);
            if (null == linkdata)
            {
                SetExcuteLine(2);
                return false;
            }
            //把字母变成大小
            linkdata = linkdata.ToUpper();
            adddata = data.adddata[0].ToString().ToUpper();

            datalocate = data.addlocate;
            cur_find = -1;

            editsd = EditLinkState.edit_find;
            all_size = linkdata.Length;
            cur_size = all_size;
            for (int i = 0; i < linkdata.Length; ++i)
            {
                Link_Data[i] = linkdata[i];
            }
            return true;
        }

        public bool ResetData(GlobalLink.LinkDelData data)
        {
            operateType = LinkOperateType.Delete;
            string linkdata;
            // 去掉空字符
            linkdata = data.linkdata.Trim();
            if (null == linkdata)
            {
                return false;
            }
            //把字母变成大小
            linkdata = linkdata.ToUpper();

            datalocate = data.dellocate;
            cur_find = -1;

            editsd = EditLinkState.edit_find;
            all_size = linkdata.Length;
            cur_size = all_size;
            for (int i = 0; i < linkdata.Length; ++i)
            {
                Link_Data[i] = linkdata[i];
            }
            return true;
        }

        public string SearchData = "";
        public bool ResetData(string data,string searchdata)
        {
            operateType = LinkOperateType.Search;
            string linkdata;
            // 去掉空字符
            linkdata = data.Trim();
            if (null == linkdata)
            {
                return false;
            }
            //把字母变成大小
            linkdata = linkdata.ToUpper();

            SearchData = searchdata;
            cur_find = -1;
            
            all_size = linkdata.Length;
            cur_size = all_size;
            for (int i = 0; i < linkdata.Length; ++i)
            {
                Link_Data[i] = linkdata[i];
            }
            return true;
        }

        public void Animation()
        {
            stop_flag = false;
            switch (operateType)
            {
                case LinkOperateType.InitNew:
                    {
                        SetExcuteLine(4);
                        initsd = InitLinkState.init_new;//当前新建操作初始化设置为第一步，画new元素
                        break;
                    }
                case LinkOperateType.AddElement:
                    {
                        SetExcuteLine(1);
                        if (datalocate <= 0)
                        {
                            SetExcuteLine(2);
                            MessageBox.Show(Animation_Form, "插入位置错误!");
                            stop_flag = true;
                            break;
                        }
                        SetExcuteLine(3);
                        SetExcuteLine(4);
                        SetExcuteLine(5);
                        if (adddata == "")
                        {
                            SetExcuteLine(6);
                            stop_flag = true;
                            break; ;
                        }
                        
                        editsd = EditLinkState.edit_find;
                        linestep = 0;
                    }
                    break;

                case LinkOperateType.Delete:
                    {
                        SetExcuteLine(1);
                        if (datalocate <= 0)
                        {
                            SetExcuteLine(2);
                            return;
                        }
                        SetExcuteLine(3);
                        editsd = EditLinkState.edit_find;
                        linestep = 0;
                    }
                    break;
                case LinkOperateType.Search:
                    {
                        SetExcuteLine(0);
                        if (PublicDataClass.IsSearchForIndex && Convert.ToUInt32(SearchData) <= 0)
                        {
                            MessageBox.Show(Animation_Form, "查找位置错误!");
                            stop_flag = true; 
                            break;
                        }
                    } break;
            }
            if (stop_flag != true)
            {
                switch (operateType)
                {
                    case LinkOperateType.InitNew:
                        stop_flag = Animation_Init();
                        break;
                    case LinkOperateType.AddElement:
                        stop_flag = Animation_Add();
                        break;
                    case LinkOperateType.Delete:
                        stop_flag = Animation_Del();
                        break;
                    case LinkOperateType.Search:
                        stop_flag = Animation_Search();
                        break;
                }
            }
            if (stop_flag)
            {
                MessageBox.Show(Animation_Form,"演示结束!");
                SysMainForm.AnimationForm.ChangeExcuteOverBtnsEnable();             
            }
            
        }




        private int Element_width = 80;
        private int Element_height = 50;
        private int Finger_width = 20;
        private int cur_size = 0;
        private int cur_find = -1;
        private int all_size = 0;

        public struct LocationPoint
        {
            public int Location_x;
            public int Location_y;
        }
        public LocationPoint locationpoint;

        /// <summary>
        /// 画链表元素
        /// </summary>
        public void DrawElement(int x, int y, String data, SolidBrush emBrush, SolidBrush fgBrush, SolidBrush fontBrush)
        {
            if (null == data)
            {
                return;
            }
            BufferGrap.DrawRectangle(new Pen(Color.White), x, y, Element_width, Element_height);
            BufferGrap.DrawRectangle(new Pen(Color.White), x + Element_width, y, Finger_width, Element_height);
            BufferGrap.FillRectangle(emBrush, x + 2, y + 2, Element_width - 4, Element_height - 4);
            BufferGrap.FillRectangle(fgBrush, x + Element_width + 2, y + 2, Finger_width - 4, Element_height - 4);
            BufferGrap.DrawString(data, new Font("微软雅黑", 15), fontBrush, x + Element_width / 3, y + Element_height / 3);
        }
        /// <summary>
        /// 画连接线
        /// </summary>
        /// <returns></returns>
        private void DrawLinkline(LocationPoint startpoint, LocationPoint overpoint)
        {
            int x1 = startpoint.Location_x;
            int y1 = startpoint.Location_y;
            int x2 = overpoint.Location_x;
            int y2 = overpoint.Location_y;

            Point pt1 = new Point(x1, y1);
            Point pt2 = new Point(x2, y2);
            Point pt3 = new Point(x1 + 20, y1);
            Point pt4 = new Point(x1 + 20, y1 + 115);
            Point pt5 = new Point(x2 - 25, y2 - 35);
            Point pt6 = new Point(x2 - 25, y2);

            if (startpoint.Location_y == overpoint.Location_y)
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt1, pt2);
            }
            else
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt1, pt3);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt3, pt4);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt4, pt5);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt5, pt6);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt6, pt2);
            }
        }
        /// <summary>
        /// 绘制两个Point之间的折线
        /// </summary>
        /// <param name="pen"></param>
        /// <param name="startpoint"></param>
        /// <param name="overpoint"></param>
        private void DrawLinkline(Pen pen, Point startpoint, Point overpoint)
        {
            int x1 = startpoint.X;
            int y1 = startpoint.Y;
            int x2 = overpoint.X;
            int y2 = overpoint.Y;

            Point pt1 = new Point(x1, y1);
            Point pt2 = new Point(x2, y2);
            Point pt3 = new Point(x1 + 20, y1);
            Point pt4 = new Point(x1 + 20, y1 + 115);
            Point pt5 = new Point(x2 - 25, y2 - 35);
            Point pt6 = new Point(x2 - 25, y2);

            if (startpoint.Y == overpoint.Y)
            {
                BufferGrap.DrawLine(pen, pt1, pt2);
            }
            else
            {
                BufferGrap.DrawLine(pen, pt1, pt3);
                BufferGrap.DrawLine(pen, pt3, pt4);
                BufferGrap.DrawLine(pen, pt4, pt5);
                BufferGrap.DrawLine(pen, pt5, pt6);
                BufferGrap.DrawLine(pen, pt6, pt2);
            }
        }

        /// <summary>
        /// 绘制(x1,y1)到(x2,y2)的折线
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>

        private void DrawLinkline(int x1, int y1, int x2, int y2)
        {

            Point pt1 = new Point(x1, y1);
            Point pt2 = new Point(x2, y2);
            Point pt3 = new Point(x1 + 20, y1);
            Point pt4 = new Point(x1 + 20, y1 + 115);
            Point pt5 = new Point(x2 - 25, y2 - 35);
            Point pt6 = new Point(x2 - 25, y2);

            if (y1 == y2)
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt1, pt2);
            }
            else
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt1, pt3);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt3, pt4);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt4, pt5);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt5, pt6);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), pt6, pt2);
            }
        }

        /// <summary>
        /// 绘制(x1,y1)到(x2,y2)的直线
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        private void DrawLinklines(int x1, int y1, int x2, int y2)
        {

            Point pt1 = new Point(x1, y1);
            Point pt2 = new Point(x2, y2);
            BufferGrap.DrawLine(new Pen(Color.Red, 3), pt1, pt2);

        }

        private bool Refresh()
        {
            try
            {
                if (Animation_Form.IsHandleCreated)
                    Animation_Form.Invoke(RefreshHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(Animation_Form, ex.Message);
                return false;
            }
            return true;
        }

        //重新设置双缓冲画布和Graphics
        public void ResetBuffer(int Width, int Height)
        {
            this.Animation_width = Width;
            this.Animation_height = Height;
            if (null != BufferBmp)
            {
                BufferBmp.Dispose();
                BufferBmp = null;
            }
            if (null != BufferGrap)
            {
                BufferGrap.Dispose();
                BufferGrap = null;
            }

            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);
            DrawLinkData();
        }
        /// <summary>
        /// 枚举链表状态
        /// </summary>
        public enum InitLinkState
        {
            init_new,
            init_linkold,
            init_linknew,
            init_add,
        }
        /// <summary>
        /// 枚举操作链表的状态
        /// </summary>
        public enum EditLinkState
        {
            edit_find,
            edit_add,
            edit_line,
            edit_update,
        }

        private int addx;
        private int addy;

        private InitLinkState initsd;
        private EditLinkState editsd;

        private Bitmap Backpicture = PublicDataClass.DemoPicture;
        /// <summary>
        /// 新建链表动画实现
        /// </summary>
        /// <returns></returns>
        public bool Animation_Init()
        {
            while (cur_size < all_size)
            {
                Thread.Sleep(_Speed * 5);
                BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                switch (initsd)
                {
                    case InitLinkState.init_new: Init_NewElement();
                        break;
                    case InitLinkState.init_linkold: Init_LinkOld();
                        break;
                    case InitLinkState.init_linknew: Init_LinkNew();
                        break;
                    case InitLinkState.init_add: Init_LinkAdd();
                        break;
                }
                DrawLinkData();
                Refresh();
                if (cur_size == all_size)
                {
                    SetExcuteLine(10);
                }
            }
            return true;
        }

        public bool Animation_Add()
        {
            while (editsd != EditLinkState.edit_update)
            {                
                Thread.Sleep(_Speed * 20);
                switch (editsd)
                {
                    case EditLinkState.edit_find:
                        {
                            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                            EditLink_Find();
                            DrawLinkData();
                            Refresh();
                            SetExcuteLine(9);
                            if (cur_find >= all_size)
                            {
                                SetExcuteLine(10);
                                MessageBox.Show(Animation_Form, "插入位置错误!");
                                return true;
                            }
                        }
                        break;
                    case EditLinkState.edit_add:
                        {
                            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                            DrawLinkData();
                            EditLink_Add();
                            Refresh();
                        }
                        break;
                    case EditLinkState.edit_line:
                        {
                            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                            DrawLinkData();
                            EditLink_AddLine();
                            Refresh();
                        }
                        break;
                }
                
            }
            SetExcuteLine(12);
            Thread.Sleep(_Speed * 20);
            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
            DrawLinkData();
            Refresh();
            SetExcuteLine(13);
            return true;
        }


        public bool Animation_Del()
        {
            while (editsd != EditLinkState.edit_update)
            {
                Thread.Sleep(_Speed * 20);
                 
                switch (editsd)
                {
                    case EditLinkState.edit_find:
                        {
                            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                            EditLink_Find();
                            DrawLinkData();
                            Refresh();
                            SetExcuteLine(6);
                            if (cur_find >= all_size)
                            {
                                SetExcuteLine(7);
                                MessageBox.Show(Animation_Form, "删除位置错误!");
                                return true;
                            }
                        }
                        break;
                    case EditLinkState.edit_line:
                        {
                            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                            DrawLinkData();
                            EditLink_DelLine();
                            Refresh();
                        }
                        break;
                }
                
            } 
            
            SetExcuteLine(9);
            Thread.Sleep(_Speed * 20);
            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
            DrawLinkData();
            Refresh();
            SetExcuteLine(10);            
            return true;
        }

        public bool Animation_Search()
        {
            Thread.Sleep(_Speed * 20);
            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
            DrawLinkData();
            Refresh();
            SetExcuteLine(1);
            SetExcuteLine(2);
            SetExcuteLine(3);
            while (cur_find<all_size)
            {
                
                SetExcuteLine(4);
                switch (PublicDataClass.IsSearchForIndex)
                {
                    case false:
                        {
                            SetExcuteLine(5);
                            SetExcuteLine(6);
                            if (cur_find==-1)
                            {
                                SetExcuteLine(7);
                                cur_find++;
                                Thread.Sleep(_Speed * 20);
                                BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                                DrawLinkData();
                                Refresh();
                            }
                            else if (Link_Data[cur_find].ToString() != SearchData.ToUpper())
                            {
                                SetExcuteLine(7);
                                cur_find++;
                                Thread.Sleep(_Speed * 20);
                                BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                                DrawLinkData();
                                Refresh();
                            }
                            else 
                            {
                                SetExcuteLine(8);
                                SetExcuteLine(9);
                                MessageBox.Show(Animation_Form, "查找成功,位置为" + (cur_find + 1));
                                SetExcuteLine(10);
                                return true;
                            }
                            SetExcuteLine(11);
                        }
                        break;
                    case true:
                        {
                            SetExcuteLine(12);
                            if (cur_find == Convert.ToUInt32(SearchData) - 1)
                            {
                                SetExcuteLine(13);
                                SetExcuteLine(14);
                                MessageBox.Show(Animation_Form, "查找成功,索引值为" + Link_Data[cur_find]);
                                SetExcuteLine(15);
                                return true;
                            }
                            else
                            {
                                SetExcuteLine(16);
                                SetExcuteLine(17);
                                cur_find++;
                                Thread.Sleep(_Speed * 20);
                                BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
                                DrawLinkData();
                                Refresh();
                                SetExcuteLine(18);
                            }
                            SetExcuteLine(19);
                        }
                        break;
                }
                
                SetExcuteLine(3);
            }
            SetExcuteLine(22);
            MessageBox.Show(Animation_Form, "查找失败!");
            SetExcuteLine(23);
            return true;
        }



        /// <summary>
        /// 画出新的链表元素动画
        /// </summary>
        public void Init_NewElement()
        {
            SetExcuteLine(5);
            if (cur_size < all_size)
            {
                DrawElement(350, 50, Link_Data[all_size - cur_size - 1].ToString(), new SolidBrush(Color.Blue), new SolidBrush(Color.Gray), new SolidBrush(Color.Yellow));
            }
            initsd = InitLinkState.init_linkold;
            addx = 0;
            addy = 0;
        }

        public void Init_LinkOld()
        {
            if (cur_size < all_size)
            {
                DrawElement(350, 50, Link_Data[all_size - cur_size - 1].ToString(), new SolidBrush(Color.Blue), new SolidBrush(Color.Gray), new SolidBrush(Color.Yellow));
            }
            if (cur_size == 0)
            {
                SetExcuteLine(6);
                initsd = InitLinkState.init_linknew;
                addx = 0;
                addy = 0;
                return;
            }
            SetExcuteLine(7);


            ///画链接链表旧元素的连接线
            if (addx <= 2 && addy == 0)
            {
                DrawLinklines(450, 75, 450 + addx * 10, 75);
                if (addx < 2)
                {
                    ++addx;
                }

            }
            if (addx >= 2 && addy <= 5)
            {
                DrawLinklines(450, 75, 470, 75);
                DrawLinklines(470, 75, 470, 75 + addy * 10);
                ++addy;
            }
            if (addy > 5 && addx > -30)
            {
                DrawLinklines(450, 75, 470, 75);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(470, 75), new Point(470, 125));
                DrawLinklines(470, 125, 450 + addx * 10, 125);
                --addx;
            }
            if (addx <= -30 && addy <= 8)
            {
                DrawLinklines(450, 75, 470, 75);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(470, 75), new Point(470, 125));
                DrawLinklines(470, 125, 160, 125);
                DrawLinklines(160, 125, 160, 75 + addy * 10);
                ++addy;
            }
            if (addy > 8)
            {
                initsd = InitLinkState.init_linknew;
                addx = 0;
                addy = 0;
            }
        }

        public void Init_LinkNew()
        {
            if (cur_size < all_size)
            {
                DrawElement(350, 50, Link_Data[all_size - cur_size - 1].ToString(), new SolidBrush(Color.Blue), new SolidBrush(Color.Gray), new SolidBrush(Color.Yellow));
            }
            if (cur_size > 0)
            {
                DrawLinkline(450, 75, 470, 75);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(470, 75), new Point(470, 125));
                DrawLinkline(470, 125, 160, 125);
                BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(160, 125), new Point(160, 150));
            }
            SetExcuteLine(8);
            if (addx <= 15)
            {
                DrawLinkline(200, 75, 200 + addx * 10, 75);
                addx++;
            }
            if (addx > 15)
            {
                initsd = InitLinkState.init_add;
                addx = 0;
                addy = 0;
            }
        }
        public void Init_LinkAdd()
        {
            SetExcuteLine(4);
            initsd = InitLinkState.init_new;
            ++cur_size;
        }

        /// <summary>
        /// 查找链表要编辑的位置
        /// </summary>
        public void EditLink_Find()
        {
            if (operateType == LinkOperateType.Delete)
            {
                SetExcuteLine(4);
            }
            else
            {
                SetExcuteLine(7);
            }
            if (cur_find + 1 < datalocate)
            {
                if (operateType == LinkOperateType.Delete)
                {
                    SetExcuteLine(5);
                }
                else if(operateType == LinkOperateType.AddElement)
                {
                    SetExcuteLine(8);
                }
                cur_find++;
            }
            if (cur_find + 1 == datalocate)
            {
                if (operateType == LinkOperateType.AddElement)
                {

                    editsd = EditLinkState.edit_add;
                }
                else
                {
                    linestep = 1;
                    editsd = EditLinkState.edit_line;
                }
            }
        }

        public void EditLink_Add()
        {
            SetExcuteLine(9);
            DrawElement(50 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, adddata, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), new SolidBrush(Color.Yellow));
            editsd = EditLinkState.edit_line;
        }

        public int linestep = 0;
        public void EditLink_AddLine()
        {
            switch (linestep)
            {
                case 0:

                    //DrawElement(50 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, adddata, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), new SolidBrush(Color.Yellow));
                    //if (datalocate <= all_size)
                    //{
                    //    DrawLinklines(140 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, 140 + ((datalocate - 1) % 3) * 250, 200 + ((datalocate - 1) / 3) * 150);
                    //}
                    //linestep = 1;
                    //break;
                case 1:
                    {

                        SetExcuteLine(11);
                        //画要添加的元素
                        DrawElement(50 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, adddata, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), new SolidBrush(Color.Yellow));
                        //连接新元素和原来链表元素
                        if (datalocate <= all_size)
                        {
                            DrawLinklines(140 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, 140 + ((datalocate - 1) % 3) * 250, 200 + ((datalocate - 1) / 3) * 150);
                        }

                        linestep = 2;
                        break;
                    }
                case 2:
                    {
                        //画要添加的元素
                        DrawElement(50 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, adddata, new SolidBrush(Color.Red), new SolidBrush(Color.Blue), new SolidBrush(Color.Yellow));
                        //连接新元素和原来链表元素
                        if (datalocate <= all_size)
                        {
                            DrawLinklines(140 + ((datalocate - 1) % 3) * 250, 230 + ((datalocate - 1) / 3) * 150, 140 + ((datalocate - 1) % 3) * 250, 200 + ((datalocate - 1) / 3) * 150);
                        }
                        if (datalocate == 1)
                        {
                            //当添加位置是在第一个的时候
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(100, 75), new Point(75, 75));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(75, 75), new Point(75, 230));
                        }
                        else if (datalocate % 3 != 1)
                        {
                            //当添加的元素不是在最左边的时候
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(((datalocate - 1) % 3) * 250 - 60, 200 + ((datalocate - 1) / 3) * 150),
                                new Point(((datalocate - 1) % 3) * 250 - 60, 255 + ((datalocate - 1) / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(((datalocate - 1) % 3) * 250 - 60, 255 + ((datalocate - 1) / 3) * 150),
                                new Point(((datalocate - 1) % 3) * 250 + 50, 255 + ((datalocate - 1) / 3) * 150));
                        }
                        else if (datalocate % 3 == 1)
                        {
                            //当添加元素是在最左边的时候
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(700, 25 + ((datalocate - 1) / 3) * 150), new Point(720, 25 + ((datalocate - 1) / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(720, 25 + ((datalocate - 1) / 3) * 150), new Point(720, 140 + ((datalocate - 1) / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(720, 140 + ((datalocate - 1) / 3) * 150), new Point(75, 140 + ((datalocate - 1) / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(75, 140 + ((datalocate - 1) / 3) * 150), new Point(75, 230 + ((datalocate - 1) / 3) * 150));
                        }
                        int i;
                        for (i = all_size; i >= datalocate; --i)
                        {
                            Link_Data[i] = Link_Data[i - 1];
                        }
                        Link_Data[i] = adddata[0];
                        all_size++;
                        cur_size++;
                        editsd = EditLinkState.edit_update;
                        break;
                    }

            }
        }

        public void EditLink_DelLine()
        {
            switch (linestep)
            {
                case 1:
                    {
                        SetExcuteLine(6);
                        linestep = 2;
                    }
                    break;
                case 2:
                    {
                        SetExcuteLine(8);
                        if (datalocate == 1)
                        {
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(200, 75), new Point(390, 75));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(390, 75), new Point(390, 150));
                        }
                        else if (datalocate % 3 == 2 && datalocate != all_size)
                        {
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(190, 200 + (datalocate / 3) * 150), new Point(190, 230 + (datalocate / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(190, 230 + (datalocate / 3) * 150), new Point(640, 230 + (datalocate / 3) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(640, 230 + (datalocate / 3) * 150), new Point(640, 200 + (datalocate / 3) * 150));
                        }
                        else if (datalocate != all_size)
                        {

                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(390 + (datalocate % 3) * 250, 200 + ((datalocate / 3 - 1)) * 150), new Point(390 + (datalocate % 3) * 250, 230 + ((datalocate / 3 - 1)) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(390 + (datalocate % 3) * 250, 230 + ((datalocate / 3 - 1)) * 150), new Point(140 + (datalocate % 3) * 250, 230 + ((datalocate / 3 - 1)) * 150));
                            BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(140 + (datalocate % 3) * 250, 230 + ((datalocate / 3 - 1)) * 150), new Point(140 + (datalocate % 3) * 250, 300 + ((datalocate / 3 - 1)) * 150));
                        }
                        else
                        {
                        }
                        int i;
                        for (i = datalocate; i < all_size; ++i)
                        {
                            Link_Data[i - 1] = Link_Data[i];
                        }
                        all_size--;
                        cur_size--;
                        editsd = EditLinkState.edit_update;
                        break;
                    }

            }
        }

        public LocationPoint SetLocationPoint(int x, int y)
        {
            locationpoint.Location_x = x;
            locationpoint.Location_y = y;
            return locationpoint;
        }

        private SolidBrush elecolor = new SolidBrush(Color.Blue);
        private SolidBrush poscolor = new SolidBrush(Color.Gray);
        private SolidBrush datacolor = new SolidBrush(Color.Yellow);
        public void DrawLinkData()
        {
            if (cur_find == -1)
            {
                elecolor.Color = Color.Red;
                poscolor.Color = Color.Yellow;
                datacolor.Color = Color.Blue;
            }
            else
            {
                elecolor.Color = Color.Blue;
                poscolor.Color = Color.Gray;
                datacolor.Color = Color.Yellow;
            }
            DrawElement(100, 50, "top", elecolor, poscolor, datacolor);
            if (cur_size == 0)
            {
                return;
            }
            if (operateType == LinkOperateType.InitNew && (initsd == InitLinkState.init_linknew || initsd == InitLinkState.init_add))
            {
                //初始化操作时，连接新元素的时候不画top到第一个元素的线
            }
            else if (operateType == LinkOperateType.AddElement && datalocate == 1 && linestep == 2 && editsd == EditLinkState.edit_line)
            {
                //添加操作的时候，添加在位置 1，表头top连接新元素的时候，不画线
            }
            else if (operateType == LinkOperateType.Delete && datalocate == 1 && linestep == 2 && editsd == EditLinkState.edit_line)
            {
                //删除操作，要删除第一个元素，连接第二个元素的时候，不画线
            }
            else
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 3), new Point(150, 100), new Point(150, 150));
            }
            int x = 100;
            int y = 150;
            LocationPoint xpoint;
            LocationPoint ypoint;
            for (int i = 0; i < cur_size; ++i)
            {
                if (cur_find == i)
                {
                    elecolor.Color = Color.Red;
                    poscolor.Color = Color.Yellow;
                    datacolor.Color = Color.Blue;
                }
                else
                {
                    elecolor.Color = Color.Blue;
                    poscolor.Color = Color.Gray;
                    datacolor.Color = Color.Yellow;
                }
                DrawElement(x + (i % 3) * 250, y + (i / 3) * 150, Link_Data[all_size - cur_size + i].ToString(), elecolor, poscolor, datacolor);
                if (i < cur_size - 1)
                {
                    if (operateType != LinkOperateType.InitNew && editsd == EditLinkState.edit_line && linestep != 0 && datalocate == i + 2)
                    {
                    }
                    else
                    {
                        xpoint = SetLocationPoint(x + Element_width + Finger_width + (i % 3) * 250, y + Element_height / 2 + (i / 3) * 150);
                        ypoint = SetLocationPoint(x + ((i + 1) % 3) * 250, y + Element_height / 2 + ((i + 1) / 3) * 150);
                        DrawLinkline(xpoint, ypoint);
                    }
                }
            }
            if (operateType == LinkOperateType.Search)
            {
                string str = "";
                switch (PublicDataClass.IsSearchForIndex)
                {
                    case true:
                        str = "按位查找，查找第" + SearchData + "位。";
                        break;
                    case false:
                        str = "按值查找，查找" + SearchData.ToUpper();
                        break;
                }
                BufferGrap.DrawString(str, new Font("微软雅黑", 15), Brushes.YellowGreen, 20, Animation_height - 50);
            }

        }
        public void InitData()
        {
            ResetBuffer(Animation_width, Animation_height);
            operateType = GlobalLink.operateType;
            switch (operateType)
            {
                case LinkOperateType.InitNew:
                    GlobalLink.linknewdata = PublicDataClass.InitData;
                    ResetData(GlobalLink.linknewdata);
                    break;
                case LinkOperateType.AddElement:
                    GlobalLink.linkadddata.linkdata = PublicDataClass.InitData;
                    GlobalLink.linkadddata.adddata = PublicDataClass.InsertData;
                    GlobalLink.linkadddata.addlocate = PublicDataClass.LocateData;
                    ResetData(GlobalLink.linkadddata);
                    break;
                case LinkOperateType.Delete:
                    GlobalLink.linkdeldata.linkdata = PublicDataClass.InitData;
                    GlobalLink.linkdeldata.dellocate = PublicDataClass.LocateData;
                    ResetData(GlobalLink.linkdeldata);
                    break;
                case LinkOperateType.Search:
                    GlobalLink.linknewdata = PublicDataClass.InitData;
                    GlobalLink.linksearchdata = PublicDataClass.SearchData;
                    ResetData(GlobalLink.linknewdata, GlobalLink.linksearchdata);
                    break;
            }
            BufferGrap.DrawImage(Backpicture, 0, 0, Animation_width, Animation_height);
            DrawLinkData();    

            Refresh();
        }
        public void ResetData()
        {
            InitData();
        }
        public Bitmap GetBufferBmp()
        {
            return BufferBmp;
        }
        private void SetExcuteLine(int line)
        {
            if (line != GlobalLink.cur_line)
            {
                GlobalLink.cur_line = line;
                Thread.Sleep((int)(800 * PublicDataClass.scale));
                SysMainForm.AnimationForm.SetSelectLine(line);
            }
        }
    }
}
